
/**
 * PromptSidebar - 提示词管理工具
 * Copyright (C) 2025
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 */

import type { StorageData, Prompt, Category } from '../types';

const DEFAULT_CATEGORIES: Category[] = [
  { id: 'general', name: '通用', order: 0 },
  { id: 'work', name: '工作', order: 1 },
  { id: 'study', name: '学习', order: 2 },
  { id: 'creative', name: '创意', order: 3 }
];

const DEFAULT_PROMPTS: Prompt[] = [
  {
    id: '1',
    title: '自我介绍',
    content: '你好，我是${name}，来自${company}，很高兴认识大家！',
    category: 'general',
    shortcut: '/intro',
    variables: ['name', 'company'],
    createdAt: Date.now(),
    updatedAt: Date.now()
  },
  {
    id: '2',
    title: '会议总结',
    content: '今天的会议主要讨论了${topic}，决定了${decision}，下一步行动是${action}。',
    category: 'work',
    shortcut: '/meeting',
    variables: ['topic', 'decision', 'action'],
    createdAt: Date.now(),
    updatedAt: Date.now()
  }
];

const DEFAULT_SETTINGS = {
  shortcutKey: 'Ctrl+Shift+P',
  autoReplace: true,
  doubleCtrlDelay: 300
};

// 使用 WXT storage.defineItem 定义存储项
export const promptsItem = storage.defineItem<Prompt[]>('local:prompts', {
  fallback: DEFAULT_PROMPTS,
});

export const categoriesItem = storage.defineItem<Category[]>('local:categories', {
  fallback: DEFAULT_CATEGORIES,
});

export const settingsItem = storage.defineItem<StorageData['settings']>('local:settings', {
  fallback: DEFAULT_SETTINGS,
});

export class StorageManager {
  static async getAll(): Promise<StorageData> {
    try {
      const [prompts, categories, settings] = await Promise.all([
        promptsItem.getValue(),
        categoriesItem.getValue(),
        settingsItem.getValue()
      ]);
      
      return {
        prompts: prompts || DEFAULT_PROMPTS,
        categories: categories || DEFAULT_CATEGORIES,
        settings: settings || DEFAULT_SETTINGS
      };
    } catch (error) {
      console.error('获取存储数据失败:', error);
      return {
        prompts: DEFAULT_PROMPTS,
        categories: DEFAULT_CATEGORIES,
        settings: DEFAULT_SETTINGS
      };
    }
  }

  static async getPrompts(): Promise<Prompt[]> {
    return await promptsItem.getValue() || DEFAULT_PROMPTS;
  }

  static async getCategories(): Promise<Category[]> {
    return await categoriesItem.getValue() || DEFAULT_CATEGORIES;
  }

  static async savePrompt(prompt: Prompt): Promise<void> {
    const prompts = await promptsItem.getValue() || [];
    const existingIndex = prompts.findIndex(p => p.id === prompt.id);
    
    if (existingIndex >= 0) {
      prompts[existingIndex] = { ...prompt, updatedAt: Date.now() };
    } else {
      prompts.push({ ...prompt, createdAt: Date.now(), updatedAt: Date.now() });
    }
    
    await promptsItem.setValue(prompts);
  }

  // 添加新提示词
  static async addPrompt(promptData: Omit<Prompt, 'id' | 'createdAt' | 'updatedAt'>): Promise<void> {
    const prompts = await promptsItem.getValue() || [];
    const newPrompt: Prompt = {
      ...promptData,
      id: Date.now().toString(),
      createdAt: Date.now(),
      updatedAt: Date.now()
    };
    
    prompts.push(newPrompt);
    await promptsItem.setValue(prompts);
  }

  // 更新现有提示词
  static async updatePrompt(id: string, promptData: Partial<Omit<Prompt, 'id' | 'createdAt'>>): Promise<void> {
    const prompts = await promptsItem.getValue() || [];
    const existingIndex = prompts.findIndex(p => p.id === id);
    
    if (existingIndex >= 0) {
      prompts[existingIndex] = {
        ...prompts[existingIndex],
        ...promptData,
        updatedAt: Date.now()
      };
      await promptsItem.setValue(prompts);
    } else {
      throw new Error('提示词不存在');
    }
  }

  static async deletePrompt(id: string): Promise<void> {
    const prompts = await promptsItem.getValue() || [];
    const filteredPrompts = prompts.filter(p => p.id !== id);
    await promptsItem.setValue(filteredPrompts);
  }

  static async saveCategory(category: Category): Promise<void> {
    const categories = await categoriesItem.getValue() || [];
    const existingIndex = categories.findIndex(c => c.id === category.id);
    
    if (existingIndex >= 0) {
      categories[existingIndex] = category;
    } else {
      categories.push(category);
    }
    
    await categoriesItem.setValue(categories);
  }

  // 添加新分类
  static async addCategory(categoryData: Omit<Category, 'id'>): Promise<void> {
    const categories = await categoriesItem.getValue() || [];
    const newCategory: Category = {
      ...categoryData,
      id: Date.now().toString(),
      order: categories.length
    };
    
    categories.push(newCategory);
    await categoriesItem.setValue(categories);
  }

  static async deleteCategory(id: string): Promise<void> {
    const [categories, prompts] = await Promise.all([
      categoriesItem.getValue() || [],
      promptsItem.getValue() || []
    ]);
    
    const filteredCategories = categories.filter(c => c.id !== id);
    // 将该分类下的提示词移动到通用分类
    const updatedPrompts = prompts.map(p => 
      p.category === id ? { ...p, category: 'general' } : p
    );
    
    await Promise.all([
      categoriesItem.setValue(filteredCategories),
      promptsItem.setValue(updatedPrompts)
    ]);
  }

  static async updateSettings(settings: Partial<StorageData['settings']>): Promise<void> {
    const currentSettings = await settingsItem.getValue() || DEFAULT_SETTINGS;
    const updatedSettings = { ...currentSettings, ...settings };
    await settingsItem.setValue(updatedSettings);
  }

  // 导入数据
  static async importData(importData: { prompts: Prompt[], categories: Category[] }): Promise<void> {
    try {
      // 验证数据格式
      if (!Array.isArray(importData.prompts) || !Array.isArray(importData.categories)) {
        throw new Error('导入数据格式不正确');
      }

      // 为导入的数据生成新的ID和时间戳，避免ID冲突
      const currentTime = Date.now();
      
      // 处理分类数据
      const processedCategories = importData.categories.map((category, index) => ({
        ...category,
        id: `imported_${currentTime}_cat_${index}`,
        order: index
      }));

      // 创建分类ID映射表
      const categoryIdMap = new Map();
      importData.categories.forEach((originalCategory, index) => {
        categoryIdMap.set(originalCategory.id, `imported_${currentTime}_cat_${index}`);
      });

      // 处理提示词数据
      const processedPrompts = importData.prompts.map((prompt, index) => ({
        ...prompt,
        id: `imported_${currentTime}_prompt_${index}`,
        category: categoryIdMap.get(prompt.category) || 'general', // 如果分类不存在，使用通用分类
        createdAt: currentTime,
        updatedAt: currentTime
      }));

      // 获取现有数据
      const [existingCategories, existingPrompts] = await Promise.all([
        categoriesItem.getValue() || [],
        promptsItem.getValue() || []
      ]);

      // 合并数据（导入的数据会添加到现有数据中）
      const mergedCategories = [...existingCategories, ...processedCategories];
      const mergedPrompts = [...existingPrompts, ...processedPrompts];

      // 保存合并后的数据
      await Promise.all([
        categoriesItem.setValue(mergedCategories),
        promptsItem.setValue(mergedPrompts)
      ]);

    } catch (error) {
      console.error('导入数据失败:', error);
      throw new Error('导入数据失败: ' + (error instanceof Error ? error.message : String(error)));
    }
  }

  // 清空所有数据并导入新数据（完全替换）
  static async replaceAllData(importData: { prompts: Prompt[], categories: Category[] }): Promise<void> {
    try {
      // 验证数据格式
      if (!Array.isArray(importData.prompts) || !Array.isArray(importData.categories)) {
        throw new Error('导入数据格式不正确');
      }

      // 直接使用导入的数据，但确保必要字段存在
      const currentTime = Date.now();
      
      const processedCategories = importData.categories.map(category => ({
        ...category,
        id: category.id || Date.now().toString(),
        order: category.order ?? 0
      }));

      const processedPrompts = importData.prompts.map(prompt => ({
        ...prompt,
        id: prompt.id || Date.now().toString(),
        createdAt: prompt.createdAt || currentTime,
        updatedAt: prompt.updatedAt || currentTime
      }));

      // 完全替换数据
      await Promise.all([
        categoriesItem.setValue(processedCategories),
        promptsItem.setValue(processedPrompts)
      ]);

    } catch (error) {
      console.error('替换数据失败:', error);
      throw new Error('替换数据失败: ' + (error instanceof Error ? error.message : String(error)));
    }
  }
}